package com.sunlands.qdcy.deskmate.util;


import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.security.KeyStore;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: xiyuefei
 * Date: 2017/9/14
 * Time: 下午1:17
 */
@Slf4j
@Component
public class PayUtils {

    //生成随机字符串
    public static String getNonce_str() {
        String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 15; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    //map转xml 加上签名信息
    public static String map2Xml(Map<String, Object> map)  {
        StringBuffer sb = new StringBuffer();
        StringBuilder sb2 = new StringBuilder();
        sb2.append("<xml>");
        for (String key : map.keySet()) {
            // sb2是用来做请求的xml参数
            sb2.append("<" + key + ">");
//            sb2.append("<![CDATA[" + map.get(key) + "]]>");
            sb2.append(map.get(key));
            sb2.append("</" + key + ">");
        }
        sb2.append("</xml>");
        return sb2.toString();
    }
    /*//解析微信返回return_code SUCCESS或FILE
    public static String getXml2Map(String resultXml) {
        String nonceStr;
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder;
        try {
            builder = dbf.newDocumentBuilder();
            InputStream inputStream = new ByteArrayInputStream(resultXml.getBytes());
            org.w3c.dom.Document doc = builder.parse(inputStream); //
            // 下面开始读取
            org.w3c.dom.Element root = doc.getDocumentElement(); // 获取根元素
            NodeList nl = root.getElementsByTagName("return_code");
            org.w3c.dom.Element el = (org.w3c.dom.Element) nl.item(0);
            org.w3c.dom.Node nd = el.getFirstChild();
            nonceStr = nd.getNodeValue();
            return nonceStr;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }*/

    public static Map xml2map(String xmlStr, boolean needRootKey) throws Exception {
        Document doc = DocumentHelper.parseText(xmlStr);
        Element root = doc.getRootElement();
        Map<String, Object> map = (Map<String, Object>) xml2map(root);
        if(root.elements().size()==0 && root.attributes().size()==0){
            return map;
        }
        if(needRootKey){
            //在返回的map里加根节点键（如果需要）
            Map<String, Object> rootMap = new HashMap<String, Object>();
            rootMap.put(root.getName(), map);
            return rootMap;
        }
        return map;
    }
    /**
     * xml转map 不带属性
     * @param e
     * @return
     */
    private static Map xml2map(Element e) {
        Map map = new LinkedHashMap();
        List list = e.elements();
        if (list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                Element iter = (Element) list.get(i);
                List mapList = new ArrayList();

                if (iter.elements().size() > 0) {
                    Map m = xml2map(iter);
                    if (map.get(iter.getName()) != null) {
                        Object obj = map.get(iter.getName());
                        if (!(obj instanceof List)) {
                            mapList = new ArrayList();
                            mapList.add(obj);
                            mapList.add(m);
                        }
                        if (obj instanceof List) {
                            mapList = (List) obj;
                            mapList.add(m);
                        }
                        map.put(iter.getName(), mapList);
                    } else
                        map.put(iter.getName(), m);
                } else {
                    if (map.get(iter.getName()) != null) {
                        Object obj = map.get(iter.getName());
                        if (!(obj instanceof List)) {
                            mapList = new ArrayList();
                            mapList.add(obj);
                            mapList.add(iter.getText());
                        }
                        if (obj instanceof List) {
                            mapList = (List) obj;
                            mapList.add(iter.getText());
                        }
                        map.put(iter.getName(), mapList);
                    } else
                        map.put(iter.getName(), iter.getText());
                }
            }
        } else
            map.put(e.getName(), e.getText());
        return map;
    }



    //随机字符串范围
    private static final String RANDOM_STR = "abcdefghijklmnopqrstuvwxyzABCDEFGHI"
            + "JKLMNOPQRSTUVWXYZ0123456789";
    private static final java.util.Random RANDOM = new java.util.Random();



    /**
     * 初始化微信证书
     * @return
     * @throws Exception
     */
    public static SSLContext initSSLContext(String mchId,String cacertpath)
            throws Exception {
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(new File(cacertpath));
        } catch (IOException e) {
            log.error("商户证书不正确-->>"+e);
            throw new Exception("证书不正确！", e);
        }

        try {
            KeyStore keystore = KeyStore.getInstance("PKCS12");
            char[] partnerId2charArray = mchId.toCharArray();
            keystore.load(inputStream, partnerId2charArray);
            return SSLContexts.custom().loadKeyMaterial(keystore, partnerId2charArray).build();
        } catch (Exception e) {
            log.error("商户秘钥不正确-->>"+e);
            throw new Exception("秘钥不正确！", e);
        } finally {
            inputStream.close();
        }
    }

    /**
     * 生成随机字符串
     * @return
     */
    public static String getRandomStr() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 16; i++) {
            sb.append(RANDOM_STR.charAt(RANDOM.nextInt(RANDOM_STR.length())));
        }
        return sb.toString();
    }

    /**
     * 发起微信支付相关请求
     * @return
     */
    public static String ssl(String url,String data,
                             String mchId,String cacertpath){
        StringBuffer message = new StringBuffer();
        try {
            //  KeyStore keyStore  = KeyStore.getInstance("PKCS12");
            SSLContext sslcontext = initSSLContext(mchId,cacertpath);
            SSLConnectionSocketFactory sslsf =
                    new SSLConnectionSocketFactory(sslcontext,
                            new String[] {  "TLSv1"},
                            null,
                            SSLConnectionSocketFactory.getDefaultHostnameVerifier());
            CloseableHttpClient httpclient = HttpClients.custom().
                    setSSLSocketFactory(sslsf).build();

            HttpPost httpost = new HttpPost(url);
            httpost.addHeader("Connection", "keep-alive");
            httpost.addHeader("Accept", "*/*");
            httpost.addHeader("Content-Type",
                    "application/x-www-form-urlencoded; charset=UTF-8");
            httpost.addHeader("Host", "api.mch.weixin.qq.com");
            httpost.addHeader("X-Requested-With", "XMLHttpRequest");
            httpost.addHeader("Cache-Control", "max-age=0");
            httpost.addHeader("User-Agent",
                    "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
            httpost.setEntity(new StringEntity(data, "UTF-8"));

            CloseableHttpResponse response = httpclient.execute(httpost);
            try {
                HttpEntity entity = response.getEntity();
                log.info("----------------------------------------");
                log.info(response.getStatusLine().getStatusCode()+"");
                if (entity != null) {
                    log.info("Response content length: " + entity.getContentLength());
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent(),"UTF-8"));
                    String text;
                    while ((text = bufferedReader.readLine()) != null) {
                        message.append(text);
                    }
                }
                EntityUtils.consume(entity);
            } catch (IOException e) {
                log.error("发起微信支付请求过程异常--》》 url={} e={}",url,e.getCause());
                e.printStackTrace();
            } finally {
                response.close();
            }
        } catch (Exception e1) {
            log.error("发起微信支付请求异常--》》"+e1);
            e1.printStackTrace();
        }
        return message.toString();
    }

   /* public static void main(String[] args){
        try {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("openid", "ssss");
            map.put("ss", 1);
            System.out.println(map2Xml(map));
            Map remap = xml2map(map2Xml(map),false);
            System.out.println(remap.get("ss"));
            System.out.println(remap.get("openid"));
        }catch (Exception e){
            e.printStackTrace();
        }

    }*/

}